package com.wfy.service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wfy.client.BrandClient;
import com.wfy.client.CategoryClient;
import com.wfy.client.GoodsClient;
import com.wfy.client.SpecClient;
import com.wfy.pojo.*;
import com.wfy.respsitory.GoodsRespsitory;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.FetchSourceFilter;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;

/**
 * @Title: SearchService
 * @Package com.wfy.service
 * @Author 王飞遥
 * @Date 2022/9/16 17:05
 */
@Service
public class SearchService {
    /**
     * 构建新增的数据
     * @param spu
     * @return
     */
    @Autowired
    BrandClient brandClient;
    @Autowired
    CategoryClient categoryClient;
    @Autowired
    GoodsClient goodsClient;
    @Autowired
    SpecClient specClient;
    @Autowired
    GoodsRespsitory goodsRespsitory;
    public static  final ObjectMapper MAPPER=new ObjectMapper();
    public GoodsEs buildGoodsEs(TbSpu spu) throws Exception {
        //创建一个新的对象
        GoodsEs goodsEs = new GoodsEs();
        //查询品牌的数据
        Brand brandInfo = brandClient.getBrandInfo(spu.getBrandId());
        //查询分类的名称
        List<String> names = categoryClient.queryNamesByIds(Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()));
        //查询spu下面所有的skus
        List<Sku> skus = goodsClient.querySkuListBySpuId(spu.getId());
        //获取到skus中所有的价格
        List<Long> price = new ArrayList<>();
        //存放柜skulist中的数据 json和map数据相近
        List<Map<String, Object>> maps = new ArrayList<Map<String, Object>>();
        //遍历skus 获取价格集合
        skus.forEach(sku -> {
            price.add(sku.getPrice());
            //创建一个map 用来存放sku中的数据 转换成json数据

            Map<String, Object> map = new HashMap<>();
            map.put("id",sku.getId());
            map.put("title",sku.getTitle());
            map.put("price",sku.getPrice());
            map.put("images", StringUtils.isNotBlank(sku.getImages())?StringUtils.split(sku.getImages(),",")[0]:"");
            maps.add(map);
        });
        //查询spu下的spuDetail的数据
        TbSpuDetail spuDetail = goodsClient.queryDetailBySpuId(spu.getId());
        //查询规格
        //获取所有规格参数 规格参数分为通用,特有
        List<SpecParam> params = specClient.queryParams(null, spu.getCid3(), null, true);
        //通用类型的key和value
        Map<Long,Object> genericSpecMap = MAPPER.readValue(spuDetail.getGenericSpec(), new TypeReference<Map<Long, Object>>() {});
        //特有类型的key和value
        Map<Long,List<Object>> specialSpecMap = MAPPER.readValue(spuDetail.getSpecialSpec(), new TypeReference<Map<Long, List<Object>>>() {});
        //定义map接受 {规格参数名,规格参数值}
        Map<String,Object> paramMap=new HashMap<>();
        for (SpecParam param : params) {
            //判断是否是通用属性
            if(param.getGeneric()){
                String  value = genericSpecMap.get(param.getId()).toString();
                //是否是数值类型
                if(param.getNumeric()){
                    //true 判断如果是数值,判断该数值在哪个区间
                    value=chooesSeqmnt(value,param);
                }
                //把参数名和值放入到结果集合中
                paramMap.put(param.getName(),value);
            }else{
                paramMap.put(param.getName(),specialSpecMap.get(param.getId()));
            }
        }

        //设置参数
        goodsEs.setId(spu.getId());
        goodsEs.setCid1(spu.getCid1());
        goodsEs.setCid2(spu.getCid2());
        goodsEs.setCid3(spu.getCid3());
        goodsEs.setBrandId(spu.getBrandId());
        goodsEs.setCreateTime(spu.getCreateTime());
        goodsEs.setSubTitle(spu.getSubTitle());
        goodsEs.setAll(spu.getTitle()+brandInfo.getName()+StringUtils.join(names," "));
        goodsEs.setPrice(price);
        goodsEs.setSkus(MAPPER.writeValueAsString(maps));
        goodsEs.setSpecs(paramMap);
        return goodsEs;
    }
    /**
     * 判断数值在哪个区间
     */
    public String chooesSeqmnt(String value,SpecParam param){
        double val= NumberUtils.toDouble(value);
        String reslut="其他";
        for (String s : param.getSegments().split(",")) {
            String[] split = s.split("-");
            //获取取值范围
            double begin = NumberUtils.toDouble(split[0]);
            double ebd= Double.MAX_VALUE;
            if(split.length==2){
                ebd = NumberUtils.toDouble(split[1]);
            }
            //判断是否在范围内
            if(val>=begin && val<ebd){
                if(split.length==1){
                    reslut=split[0]+param.getUnit()+"以上";
                }else if(begin==0){
                    reslut=split[1]+param.getUnit()+"以下";
                }else{
                    reslut=s+param.getUnit();
                }
                break;
            }
        }
        return reslut;
    }

    public PageResult<GoodsEs> search(SearchRequest searchRequest) {
        String key = searchRequest.getKey();
        if(StringUtils.isEmpty(key)){
            return null;
        }
        //编写构造的查询语句
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        queryBuilder.withQuery(QueryBuilders.matchQuery("all",key).operator(Operator.AND));
        //设置分页的参数
        Integer page = searchRequest.getPage();
        Integer size = searchRequest.getSize();
        queryBuilder.withPageable(PageRequest.of(page-1,size));
        //排序
        String sortBy = searchRequest.getSortBy();
        Boolean descending = searchRequest.getDescending();
        if(StringUtils.isNotEmpty(sortBy)){
            queryBuilder.withSort(SortBuilders.fieldSort(sortBy).order(descending? SortOrder.DESC:SortOrder.ASC));
        }

        //进行查询 获得结果 封装进行返回
        queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{"id","skus","subTitle"},null));
        Page<GoodsEs> search = goodsRespsitory.search(queryBuilder.build());
        //计算总条数
        Long total = search.getTotalElements();
        //180条数据每页20条 一共9页
        //187条 10页
        int totalPage=(total.intValue()+size-1)/size;
        return new PageResult<>(search.getTotalElements(),totalPage,search.getContent());
    }
}
